﻿using iTool.Cloud.Center;
using iTool.Cloud.Center.Model;
using iTool.Clustering.Center.ServiceProvider;
using Microsoft.Extensions.Options;
using Orleans;
using Orleans.Configuration;
using Orleans.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace iTool.Clustering.Center.Membership
{
    public class iCenterReminderProvider : IReminderTable
    {
        private IClusterReminderService grain;
        private ClusterOptions clusterOptions;
        private readonly IGrainReferenceConverter grainReferenceConverter;

        public iCenterReminderProvider(
            iCenterClusterClient client,
            IOptions<ClusteringStaticOptions> options,
            IOptions<ClusterOptions> clusterOptions,
            IGrainReferenceConverter grainReferenceConverter)
        {
            //var builder = new iToolClientBuilder();
            //builder.UseiCenterClustering(options.Value);
            //var client = builder.BuildAndConnectAsync().Result;
            this.grainReferenceConverter = grainReferenceConverter;
            this.clusterOptions = clusterOptions.Value;
            this.grain = client.GetGrain<IClusterReminderService>(new Random().Next(111_111_111, 999_999_999), this.clusterOptions.ToKeyString());
        }

        public async Task Init() => await this.grain.Init();

        public async Task<ReminderEntry> ReadRow(GrainReference grainRef, string reminderName)
        {
            var options = await this.grain.ReadRow(grainRef.ToKeyString(), reminderName);
            //var options = Newtonsoft.Json.JsonConvert.DeserializeObject<ReminderOptions>(result);
            return options?.ToEntry(grainReferenceConverter);
        }

        public async Task<ReminderTableData> ReadRows(GrainReference key)
        {
            var options = await this.grain.ReadRows(key.ToKeyString());
            //var options = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ReminderOptions>>(result);
            return new ReminderTableData(options.Select(x => x.ToEntry(grainReferenceConverter)));
        }

        public async Task<ReminderTableData> ReadRows(uint begin, uint end)
        {
            var options = await this.grain.ReadRows(begin, end);
            //var options = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ReminderOptions>>(result);
            return new ReminderTableData(options.Select(x => x.ToEntry(grainReferenceConverter)));
        }

        public async Task<bool> RemoveRow(GrainReference grainRef, string reminderName, string eTag)
        {
            return await this.grain.RemoveRow(grainRef.ToKeyString(), reminderName, eTag);
        }

        public async Task TestOnlyClearTable() => await this.grain.TestOnlyClearTable();

        public async Task<string> UpsertRow(ReminderEntry entry)
        {
            var updatedEtag = Guid.NewGuid().ToString();
            await this.grain.UpsertRow(entry.GrainRef.ToKeyString(), ReminderOptions.Create(entry, updatedEtag));
            return updatedEtag;
        }
    }
}
